Option Strict On
Option Explicit On 

Public Class Form
    Private ReadOnly mVisuals As Hashtable

    Public Sub New()
        mVisuals = New Hashtable
    End Sub

    Public ReadOnly Property Visuals() As Hashtable
        Get
            Return mVisuals
        End Get
    End Property
End Class
Public Class Report
    Private mFooterTop As Integer
    Private mLayout As Windows.Forms.Form
    Private mRelation As Model10.Relation 'For NoRelation
    Private mPageFooter As Model10.Section
    Private mPageHeader As Model10.Section
    Private ReadOnly mPages As Model10.PageCollection
    Private mPageSettings As Drawing.Printing.PageSettings
    Private mRightToLeft As Windows.Forms.RightToLeft
    Private mUser As Model10.User
    Private ReadOnly mVisuals As Hashtable

    Public Sub New(ByVal user As Model10.User, ByVal rightToLeft As Windows.Forms.RightToLeft, ByVal layout As Windows.Forms.Form)
        mFooterTop = 0
        mLayout = layout
        mRelation = Nothing
        mPageFooter = Nothing
        mPageHeader = Nothing
        mPages = New Model10.PageCollection
        mPageSettings = Nothing
        mRightToLeft = rightToLeft
        mUser = user
        mVisuals = New Hashtable
    End Sub

    Public Property FooterTop() As Integer
        Get
            Return mFooterTop
        End Get
        Set(ByVal Value As Integer)
            mFooterTop = Value
        End Set
    End Property
    Public Property Layout() As Windows.Forms.Form
        Get
            Return mLayout
        End Get
        Set(ByVal Value As Windows.Forms.Form)
            mLayout = Value
        End Set
    End Property
    Public Property Relation() As Model10.Relation
        Get
            Return mRelation
        End Get
        Set(ByVal Value As Model10.Relation)
            mRelation = Value
        End Set
    End Property
    Public Property PageFooter() As Model10.Section
        Get
            Return mPageFooter
        End Get
        Set(ByVal Value As Model10.Section)
            mPageFooter = Value
        End Set
    End Property
    Public Property PageHeader() As Model10.Section
        Get
            Return mPageHeader
        End Get
        Set(ByVal Value As Model10.Section)
            mPageHeader = Value
        End Set
    End Property
    Public ReadOnly Property Pages() As Model10.PageCollection
        Get
            Return mPages
        End Get
    End Property
    Public Property PageSettings() As Drawing.Printing.PageSettings
        Get
            Return mPageSettings
        End Get
        Set(ByVal Value As Drawing.Printing.PageSettings)
            mPageSettings = Value
        End Set
    End Property
    Public Property RightToLeft() As Windows.Forms.RightToLeft
        Get
            Return mRightToLeft
        End Get
        Set(ByVal Value As Windows.Forms.RightToLeft)
            mRightToLeft = Value
        End Set
    End Property
    Public Property User() As Model10.User
        Get
            Return mUser
        End Get
        Set(ByVal Value As Model10.User)
            mUser = Value
        End Set
    End Property
    Public ReadOnly Property Visuals() As Hashtable
        Get
            Return mVisuals
        End Get
    End Property


    Dim graphics As Drawing.Graphics
    Dim contentSize As Drawing.Size
    Dim name, path As String
    Dim level, index As String
    Dim tabIndex, fromTabIndex As Integer

    Private Sub RtlSection(ByVal members As Model10.MemberCollection, ByVal w As Integer)
        Dim mem As Model10.Member
        For Each mem In members
            mem.Location = New Drawing.Point(mem.Location.X + contentSize.Width - w, mem.Location.Y)
        Next : mem = Nothing
    End Sub
    Private Sub SetText(ByVal section As Model10.Section, ByVal label As Model10.Label, ByVal dataRow As DataRowView, ByVal paraRow As DataRowView, ByVal recordNumber As Integer, ByVal recordCount As Integer)
        If label.Value <> Model10.ValueType.None Then
            Select Case label.Value
                Case Model10.ValueType.DateTime
                    label.Text = FFormat(Date.Now.ToString, label.Format)
                Case Model10.ValueType.Title
                    label.Text = FFormat(section.Table.Presentation.Name, label.Format)
                Case Model10.ValueType.Path
                    label.Text = FFormat(section.Table.Presentation.Path, label.Format)
                Case Model10.ValueType.PageCount
                    label.Text = ""
                Case Model10.ValueType.PageNumber
                    label.Text = ""
                Case Model10.ValueType.RecordCount
                    label.Text = FFormat(recordCount, label.Format)
                Case Model10.ValueType.RecordNumber
                    label.Text = FFormat(recordNumber, label.Format)
                Case Model10.ValueType.UserId
                    If Not mUser Is Nothing Then label.Text = FFormat(mUser.Id, label.Format)
                Case Model10.ValueType.UserFullName
                    If Not mUser Is Nothing Then label.Text = FFormat(mUser.FullName, label.Format)
                Case Model10.ValueType.UserName
                    If Not mUser Is Nothing Then label.Text = FFormat(mUser.Name, label.Format)
            End Select
        ElseIf label.DataField <> "" Then
            Dim obj As Object
            Try
                If dataRow Is Nothing Then
                    obj = section.Table.DataTable.Columns(label.DataField).DefaultValue
                Else
                    If label.ParentRelation Is Nothing Then
                        obj = dataRow(label.DataField)
                    Else
                        obj = dataRow.Row.GetParentRow(label.ParentRelation.DataRelation)(label.DataField)
                    End If
                End If
            Catch ex As Exception
                Try
                    obj = paraRow(label.DataField)
                Catch exx As Exception
                End Try
            End Try
            If Not IsDBNull(obj) Then label.Text = FFormat(obj, label.Format)
            obj = Nothing
        ElseIf label.Expression <> "" Then
            label.Text = FFormat(section.Table.DataTable.Compute(label.Expression, label.Filter), label.Format)
        End If
    End Sub
    Private Sub FillSection(ByVal section As Model10.Section, ByVal members As Model10.MemberCollection, ByVal dataRow As DataRowView, ByVal paraRow As DataRowView, ByVal recordNumber As Integer, ByVal recordCount As Integer, ByVal x As Integer, ByVal y As Integer)
        Dim dif As Integer

        Dim mem As Model10.Member
        For Each mem In members
            If mem.Visible And mem.Printable Then
                Select Case mem.GetType.ToString
                    Case "Model10.Line"
                        section.Members.Add(New Model10.Line(CType(mem, Model10.Line)), x, y)
                    Case "Model10.Frame"
                        section.Members.Add(New Model10.Frame(CType(mem, Model10.Frame)), x, y)
                    Case "Model10.Label", "Model10.TextBox"
                        Dim lbl As New Model10.Label(CType(mem, Model10.Label))
                        SetText(section, lbl, dataRow, paraRow, recordNumber, recordCount)
                        section.Members.Add(lbl, x, y)
                        If lbl.AutoSize Then Measure(lbl, dif, graphics, mRightToLeft)
                        lbl = Nothing
                        '------------------------
                        'Case "Model10.DateTime"
                        '    Dim lbl As New Model10.Label(CType(mem, Model10.Label))
                        '    lbl.Text = Format(Date.Now.ToString, lbl.Format)
                        '    section.Members.Add(lbl)
                        '    If lbl.AutoSize Then Measure(lbl, dif, graphics, mRightToLeft)
                        '    lbl = Nothing
                        'Case "Model10.Title"
                        '    Dim lbl As New Model10.Label(CType(mem, Model10.Label))
                        '    lbl.Text = Format(name, lbl.Format)
                        '    section.Members.Add(lbl)
                        '    If lbl.AutoSize Then Measure(lbl, dif, graphics, mRightToLeft)
                        '    lbl = Nothing
                        'Case "Model10.Path"
                        '    Dim lbl As New Model10.Label(CType(mem, Model10.Label))
                        '    lbl.Text = Format(path, lbl.Format)
                        '    section.Members.Add(lbl)
                        '    If lbl.AutoSize Then Measure(lbl, dif, graphics, mRightToLeft)
                        '    lbl = Nothing
                        'Case "Model10.PageNumber"
                        '    Dim pn As New Model10.PageNumber(CType(mem, Model10.PageNumber))
                        '    'pc.Text =
                        '    section.Members.Add(pn)
                        '    If pn.AutoSize Then Measure(pn, dif, graphics, mRightToLeft)
                        '    pn = Nothing
                        'Case "Model10.PageCount"
                        '    Dim pc As New Model10.PageCount(CType(mem, Model10.PageCount))
                        '    'pc.Text =
                        '    section.Members.Add(pc)
                        '    If pc.AutoSize Then Measure(pc, dif, graphics, mRightToLeft)
                        '    pc = Nothing
                        'Case "Model10.RecordNumber"
                        '    Dim lbl As New Model10.Label(CType(mem, Model10.Label))
                        '    lbl.Text = Format(recordNumber, lbl.Format)
                        '    section.Members.Add(lbl)
                        '    If lbl.AutoSize Then Measure(lbl, dif, graphics, mRightToLeft)
                        '    lbl = Nothing
                        'Case "Model10.RecordCount"
                        '    Dim lbl As New Model10.Label(CType(mem, Model10.Label))
                        '    lbl.Text = Format(recordCount, lbl.Format)
                        '    section.Members.Add(lbl)
                        '    If lbl.AutoSize Then Measure(lbl, dif, graphics, mRightToLeft)
                        '    lbl = Nothing
                        'Case "Model10.UserId"
                        '    Dim lbl As New Model10.Label(CType(mem, Model10.Label))
                        '    If Not mUser Is Nothing Then lbl.Text = Format(mUser.Id, lbl.Format)
                        '    section.Members.Add(lbl)
                        '    If lbl.AutoSize Then Measure(lbl, dif, graphics, mRightToLeft)
                        '    lbl = Nothing
                        'Case "Model10.UserFullName"
                        '    Dim lbl As New Model10.Label(CType(mem, Model10.Label))
                        '    If Not mUser Is Nothing Then lbl.Text = Format(mUser.FullName, lbl.Format)
                        '    section.Members.Add(lbl)
                        '    If lbl.AutoSize Then Measure(lbl, dif, graphics, mRightToLeft)
                        '    lbl = Nothing
                        'Case "Model10.UserName"
                        '    Dim lbl As New Model10.Label(CType(mem, Model10.Label))
                        '    If Not mUser Is Nothing Then lbl.Text = Format(mUser.Name, lbl.Format)
                        '    section.Members.Add(lbl)
                        '    If lbl.AutoSize Then Measure(lbl, dif, graphics, mRightToLeft)
                        '    lbl = Nothing
                        '------------------------
                    Case "Model10.PictureBox"
                        Dim pic As New Model10.PictureBox(CType(mem, Model10.PictureBox))
                        If Not dataRow Is Nothing Then
                            If pic.DataField <> "" Then
                                Try
                                    Dim obj As Object = dataRow(pic.DataField)
                                    Select Case TypeName(obj)
                                        Case "Byte()" : pic.Image = GetImage(CType(obj, Byte()))
                                        Case "String" : pic.Image = Drawing.Image.FromFile(CStr(obj))
                                    End Select
                                    obj = Nothing
                                Catch ex As Exception
                                End Try
                            End If
                        End If
                        If Not pic.Image Is Nothing Then
                            pic.Key = Guid.NewGuid.ToString
                            mVisuals.Add(pic.Key, pic)
                        End If
                        section.Members.Add(pic, x, y)
                        pic = Nothing
                    Case "Model10.CheckBox"
                        Dim chk As New Model10.CheckBox(CType(mem, Model10.CheckBox))
                        If Not dataRow Is Nothing Then
                            If chk.DataField <> "" Then
                                Try
                                    Dim obj As Object = dataRow(chk.DataField)
                                    If Not IsDBNull(obj) Then chk.Checked = CBool(obj)
                                    obj = Nothing
                                Catch ex As Exception
                                End Try
                            End If
                        End If
                        section.Members.Add(chk, x, y)
                        chk = Nothing
                    Case "Model10.Sub"
                        If Not dataRow Is Nothing Then
                            Dim sb As Model10.Sub = CType(mem, Model10.Sub)
                            Dim iH As Integer = sb.Location.Y
                            If Not sb.ChildRelation Is Nothing Then
                                If Not sb.ChildRelation.ChildTable.GroupHeader Is Nothing Then
                                    FillSection(section, sb.ChildRelation.ChildTable.GroupHeader.Members, dataRow, paraRow, recordNumber, recordCount, sb.Location.X, iH)
                                    iH += sb.ChildRelation.ChildTable.GroupHeader.Height
                                End If
                                '----------------------------------
                                Dim dr As DataRowView, i As Integer
                                i = 0
                                Dim dv As DataView = dataRow.CreateChildView(sb.ChildRelation.DataRelation)
                                '-----------------Special
                                'For Each rel As DataRelation In sb.ChildRelation.DataRelation.ChildTable.ChildRelations
                                '    If rel.ChildTable Is rel.ParentTable And Not rel Is sb.ChildRelation.DataRelation Then
                                '        dv.RowFilter = rel.ChildColumns(0).ColumnName + " IS NULL"
                                '    End If
                                'Next
                                '-----------------Special
                                For Each dr In dv
                                    If mLayout Is Nothing Then
                                        Try
                                            Model10.[Global].FillChildData(sb.ChildRelation.ChildTable, paraRow, dr, mRelation)
                                        Catch ex As Exception
                                        End Try
                                    End If

                                    If Not sb.ChildRelation.ChildTable.Detail Is Nothing Then
                                        FillSection(section, sb.ChildRelation.ChildTable.Detail.Members, dr, paraRow, i + 1, dv.Count, sb.Location.X, iH)
                                        iH += sb.ChildRelation.ChildTable.Detail.Height
                                    End If
                                    i += 1
                                Next : dr = Nothing
                                dv = Nothing
                                '----------------------------------
                                If Not sb.ChildRelation.ChildTable.GroupFooter Is Nothing Then
                                    FillSection(section, sb.ChildRelation.ChildTable.GroupFooter.Members, dataRow, paraRow, recordNumber, recordCount, sb.Location.X, iH)
                                    iH += sb.ChildRelation.ChildTable.GroupFooter.Height
                                End If
                            End If
                            sb = Nothing
                        End If
                    Case "Model10.Chart"
                        Dim cht As New Model10.Chart(CType(mem, Model10.Chart))
                        section.Members.Add(cht, x, y)
                        cht = Nothing
                End Select
                If TypeOf mem Is Model10.Button Then
                    Dim btn As Model10.Button = CType(mem, Model10.Button)
                    If btn.ButtonStyle = Model10.ButtonStyle.PlusMines Then
                        section.Members.Add(New Model10.Button(CType(mem, Model10.Button)), x, y)
                    End If
                    btn = Nothing
                End If
            End If
        Next : mem = Nothing
        For Each mem In section.Members
            If mem.Visible Then
                If dif > 0 Then
                    Dim d As Integer
                    If TypeOf mem Is Model10.Label Then d = CType(mem, Model10.Label).Difference

                    If mem.Anchor = Model10.AnchorMode.TopAndBottom Then
                        mem.Size = New Drawing.Size(mem.Size.Width, mem.Size.Height + dif - d)
                    ElseIf mem.Anchor = Model10.AnchorMode.Bottom Then
                        mem.Location = New Drawing.Point(mem.Location.X, mem.Location.Y + dif - d)
                    ElseIf mem.Anchor = Model10.AnchorMode.None Then
                        mem.Location = New Drawing.Point(mem.Location.X, mem.Location.Y + (dif - d) \ 2)
                    End If
                End If
                If Not dataRow Is Nothing Then
                    If TypeOf mem Is Model10.Chart Then
                        CType(mem, Model10.Chart).FillChart(dataRow, True)
                    End If
                End If
            End If
        Next : mem = Nothing
        section.Height += dif
    End Sub
    Private Function GetContent(ByVal table As Model10.Table, ByVal paraRow As DataRowView, ByVal dataRow As DataRowView, ByVal dataView As DataView, ByVal recordNumber As Integer, ByVal recordCount As Integer, ByVal sideMargin As Integer) As Model10.Content
        GetContent = New Model10.Content(table)
        If dataView.Count > 0 Then
            If Not table.GroupHeader Is Nothing Then
                Dim bkColor As Drawing.Color
                If table.GroupHeader.PrintBackground Then
                    bkColor = table.GroupHeader.BackColor
                Else
                    bkColor = Drawing.Color.Transparent
                End If
                GetContent.GroupHeader = New Model10.Grouper(table.GroupHeader, bkcolor)

                FillSection(GetContent.GroupHeader, table.GroupHeader.Members, dataRow, paraRow, recordNumber, recordCount, 0, 0)
                GetContent.Height += GetContent.GroupHeader.Height
            End If
            '----------------------------------
            'If mRelation Is Nothing OrElse Not rel Is mRelation.DataRelation Then
            '    For Each rel As DataRelation In table.DataTable.ChildRelations
            '        If rel.ChildTable Is table.DataTable And rel.ParentTable Is table.DataTable Then
            '            dataView.RowFilter = rel.ChildColumns(0).ColumnName + " IS NULL"
            '        End If
            '    Next
            'End If

            Dim dr As DataRowView, i As Integer
            For Each dr In dataView
                Dim maxH As Integer = 0
                Dim row As New Model10.Row
                GetContent.Rows.Add(row)
                If mLayout Is Nothing Then
                    Try
                        Model10.[Global].FillChildData(table, paraRow, dr, mRelation)
                    Catch ex As Exception
                    End Try
                End If

                Dim rlt As Model10.Relation
                For Each rlt In table.ChildRelations
                    If rlt.Visible Then
                        Dim dvv As DataView = dr.CreateChildView(rlt.DataRelation)
                        '-----------------Special
                        'For Each rel As DataRelation In rlt.DataRelation.ChildTable.ChildRelations
                        '    If rel.ChildTable Is rel.ParentTable And Not rel Is rlt.DataRelation Then
                        '        dvv.RowFilter = rel.ChildColumns(0).ColumnName + " IS NULL"
                        '    End If
                        'Next
                        '-----------------Special
                        Dim con As Model10.Content = GetContent(CType(rlt.ChildTable, Model10.Table), paraRow, dr, dvv, i + 1, dataView.Count, rlt.SideMargin)
                        con.SideMargin = rlt.SideMargin
                        row.Bodies.Add(con)
                        If maxH < con.Height Then maxH = con.Height
                        con = Nothing
                    End If
                Next : rlt = Nothing

                If Not table.Detail Is Nothing Then
                    Dim bkColor As Drawing.Color
                    If table.Detail.PrintBackground Then
                        If i Mod 2 = 0 Then
                            bkColor = table.Detail.BackColor
                        Else
                            bkColor = table.Detail.AlternatingBackColor
                        End If
                    Else
                        bkColor = Drawing.Color.Transparent
                    End If
                    row.Detail = New Model10.Detail(table.Detail, bkColor)
                    FillSection(row.Detail, table.Detail.Members, dr, paraRow, i + 1, dataView.Count, 0, 0)
                    GetContent.Height += row.Detail.Height
                End If
                row = Nothing
                GetContent.Height += maxH
                i += 1
            Next : dr = Nothing
            '----------------------------------
            If Not table.GroupFooter Is Nothing Then
                Dim bkColor As Drawing.Color
                If table.GroupFooter.PrintBackground Then
                    bkColor = table.GroupFooter.BackColor
                Else
                    bkColor = Drawing.Color.Transparent
                End If
                GetContent.GroupFooter = New Model10.Grouper(table.GroupFooter, bkColor)
                FillSection(GetContent.GroupFooter, table.GroupFooter.Members, dataRow, paraRow, recordNumber, recordCount, 0, 0)
                GetContent.Height += GetContent.GroupFooter.Height
            End If
        End If
    End Function

    Private Function CloneGrouper(ByVal group As Model10.Grouper) As Model10.Grouper
        Dim bkColor As Drawing.Color
        If group.PrintBackground Then
            bkColor = group.BackColor
        Else
            bkColor = Drawing.Color.Transparent
        End If
        CloneGrouper = New Model10.Grouper(group, bkColor)

        Dim mem As Model10.Member
        For Each mem In group.Members
            If TypeOf mem Is Model10.Label Then
                CloneGrouper.Members.Add(New Model10.Label(CType(mem, Model10.Label)), 0, 0)
            ElseIf TypeOf mem Is Model10.PictureBox Then
                CloneGrouper.Members.Add(New Model10.PictureBox(CType(mem, Model10.PictureBox)), 0, 0)
            ElseIf TypeOf mem Is Model10.Frame Then
                CloneGrouper.Members.Add(New Model10.Frame(CType(mem, Model10.Frame)), 0, 0)
            ElseIf TypeOf mem Is Model10.CheckBox Then
                CloneGrouper.Members.Add(New Model10.CheckBox(CType(mem, Model10.CheckBox)), 0, 0)
            ElseIf TypeOf mem Is Model10.Line Then
                CloneGrouper.Members.Add(New Model10.Line(CType(mem, Model10.Line)), 0, 0)
            End If
        Next : mem = Nothing
    End Function
    Private Sub SetTabIndexes(ByVal section As Model10.Section)
        Dim memAr As Model10.Member() = section.GetMembers
        If Not memAr Is Nothing Then
            Dim mem As Model10.Member
            For Each mem In memAr
                If TypeOf mem Is Model10.Label Then
                    CType(mem, Model10.Label).TabIndex = tabIndex
                    tabIndex += 1
                ElseIf TypeOf mem Is Model10.PictureBox Then
                    CType(mem, Model10.PictureBox).TabIndex = tabIndex
                    tabIndex += 1
                ElseIf TypeOf mem Is Model10.CheckBox Then
                    CType(mem, Model10.CheckBox).TabIndex = tabIndex
                    tabIndex += 1
                ElseIf TypeOf mem Is Model10.Button Then
                    CType(mem, Model10.Button).TabIndex = tabIndex
                    tabIndex += 1
                End If
            Next : mem = Nothing
        End If
    End Sub
    Private Sub NewPage(ByRef pageIndex As Integer, ByRef offset As Drawing.Point)
        mPages(pageIndex).Height = offset.Y
        pageIndex += 1
        If pageIndex > mPages.Count - 1 Then
            Dim rp As New Model10.Page
            mPages.Add(rp)
            rp = Nothing
        End If
        offset.Y = 0
        tabIndex = fromTabIndex
    End Sub
    Private Sub FromSection(ByVal section As Model10.Section, ByRef pageIndex As Integer, ByVal x As Integer, ByRef y As Integer)
        Dim currentPage As Model10.Page = mPages(pageIndex)

        section.Location = New Drawing.Point(x, y)
        currentPage.Sections.Add(section)

        currentPage = Nothing
        y += section.Height
    End Sub
    Private Sub FromContent(ByVal content As Model10.Content, ByRef pageIndex As Integer, ByRef offset As Drawing.Point)
        Dim x As Integer
        If mRightToLeft = Windows.Forms.RightToLeft.Yes Then x = contentSize.Width - content.Width - offset.X Else x = offset.X

        Dim h As Integer
        Select Case content.KeepTogether
            Case KeepMode.WholeGroup
                h += content.Height
            Case KeepMode.WithFirstDetail
                If Not content.GroupHeader Is Nothing Then
                    h += content.GroupHeader.Height
                End If
                If content.Rows.Count > 0 Then
                    If Not content.Rows(0).Detail Is Nothing Then
                        h += content.Rows(0).Detail.Height
                    End If
                End If
        End Select
        If contentSize.Height - offset.Y < h And h <= contentSize.Height Then NewPage(pageIndex, offset)

        h = 0
        If Not content.GroupFooter Is Nothing Then
            If content.GroupFooter.RepeatOnEveryPage Then
                h += content.GroupFooter.Height
            End If
        End If

        If Not content.GroupHeader Is Nothing Then
            If (offset.Y > 0 And (content.GroupHeader.NewPage = NewPageMode.Before Or content.GroupHeader.NewPage = NewPageMode.BeforeAndAfter)) _
            Or contentSize.Height - offset.Y < content.GroupHeader.Height Then
                NewPage(pageIndex, offset)
            End If
            SetTabIndexes(content.GroupHeader)
            FromSection(content.GroupHeader, pageIndex, x, offset.Y)
            If (content.GroupHeader.NewPage = NewPageMode.After Or content.GroupHeader.NewPage = NewPageMode.BeforeAndAfter) Then
                NewPage(pageIndex, offset)
            End If
        End If
        '---------------------
        Dim row As Model10.Row
        For Each row In content.Rows
            If Not row.Detail Is Nothing Then
                If (offset.Y > 0 And (row.Detail.NewPage = NewPageMode.Before Or row.Detail.NewPage = NewPageMode.BeforeAndAfter)) _
                Or contentSize.Height - offset.Y < row.Detail.Height + h Then
                    If Not content.GroupFooter Is Nothing Then
                        If content.GroupFooter.RepeatOnEveryPage Then
                            SetTabIndexes(content.GroupFooter)
                            FromSection(CloneGrouper(content.GroupFooter), pageIndex, x, offset.Y)
                        End If
                    End If
                    NewPage(pageIndex, offset)
                    If Not content.GroupHeader Is Nothing Then
                        If content.GroupHeader.RepeatOnEveryPage Then
                            SetTabIndexes(content.GroupHeader)
                            FromSection(CloneGrouper(content.GroupHeader), pageIndex, x, offset.Y)
                        End If
                    End If
                End If
                SetTabIndexes(row.Detail)
                FromSection(row.Detail, pageIndex, x, offset.Y)
                If (row.Detail.NewPage = NewPageMode.After Or row.Detail.NewPage = NewPageMode.BeforeAndAfter) Then
                    NewPage(pageIndex, offset)
                End If
            End If

            Dim maxP As Integer = pageIndex
            Dim maxY As Integer = offset.Y
            Dim tmpX As Integer = 0

            Dim con As Model10.Content
            For Each con In row.Bodies
                Dim tmpO As New Drawing.Point(offset.X + tmpX + con.SideMargin, offset.Y)
                Dim tmpP As Integer = pageIndex
                FromContent(CType(con, Model10.Content), tmpP, tmpO)
                If maxP < tmpP Then
                    maxP = tmpP : maxY = tmpO.Y
                ElseIf maxP = tmpP And maxY < tmpO.Y Then
                    maxY = tmpO.Y
                End If
                tmpX += con.SideMargin + con.Width
            Next : con = Nothing

            pageIndex = maxP : offset.Y = maxY
        Next : row = Nothing
        '---------------------
        If Not content.GroupFooter Is Nothing Then
            If (offset.Y > 0 And (content.GroupFooter.NewPage = NewPageMode.Before Or content.GroupFooter.NewPage = NewPageMode.BeforeAndAfter)) _
            Or contentSize.Height - offset.Y < content.GroupFooter.Height Then
                NewPage(pageIndex, offset)
            End If
            SetTabIndexes(content.GroupFooter)
            FromSection(content.GroupFooter, pageIndex, x, offset.Y)
            If (content.GroupFooter.NewPage = NewPageMode.After Or content.GroupFooter.NewPage = NewPageMode.BeforeAndAfter) Then
                NewPage(pageIndex, offset)
            End If
        End If
    End Sub

    Public Sub FillReport(ByVal current As Model10.Current, ByVal relation As Model10.Relation, Optional ByVal l As String = "", Optional ByVal i As String = "")
        name = current.Table.Presentation.Name
        path = current.Table.Presentation.Path
        level = l : index = i

        mRelation = relation
        mPageSettings = New Drawing.Printing.PageSettings

        mVisuals.Clear()
        current.Table.WritePageSettings(mPageSettings)
        '------------------------------------------
        If mPageSettings.PrinterSettings.IsValid Then
            contentSize = mPageSettings.Bounds.Size
        Else
            contentSize = New Drawing.Size(827, 1169)
        End If
        mFooterTop = contentSize.Height - mPageSettings.Margins.Bottom
        contentSize.Width -= mPageSettings.Margins.Left + mPageSettings.Margins.Right
        contentSize.Height -= mPageSettings.Margins.Top + mPageSettings.Margins.Bottom
        If Not current.Table.PageFooter Is Nothing Then
            mPageFooter = New Model10.Pager(current.Table.PageFooter, current.Table.PageFooter.BackColor)
            FillSection(mPageFooter, current.Table.PageFooter.Members, Nothing, current.ParaRow, current.RecordNumber, current.RecordCount, 0, 0)
            tabIndex = 1000 : SetTabIndexes(mPageFooter)
            If mRightToLeft = Windows.Forms.RightToLeft.Yes Then RtlSection(mPageFooter.Members, current.Table.Width)
            contentSize.Height -= mPageFooter.Height

            mFooterTop -= mPageFooter.Height '<<
        End If
        If Not current.Table.PageHeader Is Nothing Then
            mPageHeader = New Model10.Pager(current.Table.PageHeader, current.Table.PageHeader.BackColor)
            FillSection(mPageHeader, current.Table.PageHeader.Members, Nothing, current.ParaRow, current.RecordNumber, current.RecordCount, 0, 0)
            tabIndex = 0 : SetTabIndexes(mPageHeader) : fromTabIndex = tabIndex
            If mRightToLeft = Windows.Forms.RightToLeft.Yes Then RtlSection(mPageHeader.Members, current.Table.Width)
            contentSize.Height -= mPageHeader.Height
        Else
            fromTabIndex = 0
        End If
        '------------------------------------------


        Dim bmp As New Drawing.Bitmap(1, 1)
        graphics = Drawing.Graphics.FromImage(bmp)
        '---------------
        Dim con As Model10.Content = GetContent(current.Table, current.ParaRow, current.DataRow, current.DataView, current.RecordNumber, current.RecordCount, 0)
        mPages.Clear() : mPages.Add(New Model10.Page)
        tabIndex = fromTabIndex
        Dim offset As New Drawing.Point
        FromContent(CType(con, Model10.Content), 0, offset)
        If offset.Y = 0 And mPages.Count > 1 Then mPages.RemoveAt(mPages.Count - 1)
        con = Nothing
        '---------------
        graphics.Dispose() : graphics = Nothing
        bmp.Dispose() : bmp = Nothing
    End Sub


    Dim sbStyle, sbContent As Text.StringBuilder
    Dim lines, frames, labels As ArrayList
    Dim localPictures As ArrayList
    Dim checkedImage, uncheckedImage As Boolean
    Dim path1, path2 As String
    Dim webColConverter As System.Web.UI.WebControls.WebColorConverter

    Private Function LineIndex(ByVal line As Model10.Line) As Integer
        Dim foo As String

        'Position--------------------------------------------------------------------------
        foo &= "DISPLAY: inline; "
        foo &= "OVERFLOW: hidden; "
        foo &= "POSITION: absolute; "
        'Background------------------------------------------------------------------------
        foo &= "BACKGROUND-COLOR: " & webColConverter.ConvertToString(line.BackColor) & "; "

        LineIndex = lines.IndexOf(foo)
        If LineIndex = -1 Then
            lines.Add(foo)
            LineIndex = lines.Count - 1
            sbStyle.Append(vbTab & vbTab & vbTab & ".i" & LineIndex & " {" & foo & "}" & ControlChars.NewLine)
        End If
    End Function
    Private Function FrameIndex(ByVal frame As Model10.Frame) As Integer
        Dim foo As String

        'Position--------------------------------------------------------------------------
        foo &= "DISPLAY: inline; "
        foo &= "OVERFLOW: hidden; "
        foo &= "POSITION: absolute; "
        'Background------------------------------------------------------------------------
        foo &= "BACKGROUND-COLOR: " & webColConverter.ConvertToString(frame.BackColor) & "; "
        'Border----------------------------------------------------------------------------
        Dim boColor As String
        If frame.BorderColor.Equals(Drawing.Color.Transparent) Then
            If frame.BackColor.Equals(Drawing.Color.Transparent) Then
                boColor = webColConverter.ConvertToString(frame.Section.BackColor)
            Else
                boColor = webColConverter.ConvertToString(frame.BackColor)
            End If
        Else
            boColor = webColConverter.ConvertToString(frame.BorderColor)
        End If
        foo &= "BORDER: " & boColor & " " & frame.BorderWidth.ToString & "px solid; "

        FrameIndex = frames.IndexOf(foo)
        If FrameIndex = -1 Then
            frames.Add(foo)
            FrameIndex = frames.Count - 1
            sbStyle.Append(vbTab & vbTab & vbTab & ".f" & FrameIndex & " {" & foo & "}" & ControlChars.NewLine)
        End If
    End Function
    Private Function LabelIndex(ByVal label As Model10.Label) As Integer
        Dim k As Single = label.BorderWidth
        Dim l As Single
        Select Case label.Border3DStyle
            Case Windows.Forms.Border3DStyle.Flat : l = 0
            Case Windows.Forms.Border3DStyle.RaisedInner, Windows.Forms.Border3DStyle.RaisedOuter, Windows.Forms.Border3DStyle.SunkenInner, Windows.Forms.Border3DStyle.SunkenOuter : If k < 1 Then l = 1 - k Else l = 0
            Case Windows.Forms.Border3DStyle.Bump, Windows.Forms.Border3DStyle.Etched, Windows.Forms.Border3DStyle.Raised, Windows.Forms.Border3DStyle.Sunken : If k < 2 Then l = 2 - k Else l = 0
        End Select

        Dim foo As String

        'Position--------------------------------------------------------------------------
        foo &= "DISPLAY: inline; "
        foo &= "OVERFLOW: hidden; "
        'Font------------------------------------------------------------------------------
        foo &= "FONT-FAMILY: " & label.Font.FontFamily.Name & "; "
        foo &= "COLOR: " & webColConverter.ConvertToString(label.ForeColor) & "; "
        If label.Font.Italic = True Then foo &= "FONT-STYLE: italic; "
        foo &= "FONT-SIZE: " & label.Font.SizeInPoints.ToString & "pt; "
        foo &= "LINE-HEIGHT: " & label.Font.Height.ToString & "px; "
        Dim str As String
        If label.Font.Underline Then str &= "UNDERLINE "
        If label.Font.Strikeout Then str &= "LINE-THROUGH "
        If str <> "" Then foo &= "TEXT-DECORATION: " & str.Trim & "; "
        If label.Font.Bold Then foo &= "FONT-WEIGHT: bold; "
        'StringFormat----------------------------------------------------------------------
        Select Case label.Alignment
            Case Windows.Forms.HorizontalAlignment.Left : foo &= "TEXT-ALIGN: left; "
            Case Windows.Forms.HorizontalAlignment.Right : foo &= "TEXT-ALIGN: right; "
            Case Windows.Forms.HorizontalAlignment.Center : foo &= "TEXT-ALIGN: center; "
        End Select
        Select Case label.RightToLeft
            Case Windows.Forms.RightToLeft.No : foo &= "DIRECTION: ltr; "
            Case Windows.Forms.RightToLeft.Yes : foo &= "DIRECTION: rtl; "
        End Select
        'Padding---------------------------------------------------------------------------
        If label.TopMargin + l <> 0 Then foo &= "PADDING-TOP: " & label.TopMargin + l & "px; "
        If label.BottomMargin + l <> 0 Then foo &= "PADDING-BOTTOM: " & label.BottomMargin + l & "px; "
        If label.LeftMargin + l <> 0 Then foo &= "PADDING-LEFT: " & label.LeftMargin + l & "px; "
        If label.RightMargin + l <> 0 Then foo &= "PADDING-RIGHT: " & label.RightMargin + l & "px; "

        LabelIndex = labels.IndexOf(foo)
        If LabelIndex = -1 Then
            labels.Add(foo)
            LabelIndex = labels.Count - 1
            sbStyle.Append(vbTab & vbTab & vbTab & ".l" & LabelIndex & " {" & foo & "}" & ControlChars.NewLine)
        End If
    End Function

    Private Sub HtmlLine(ByVal line As Model10.Line, ByVal indent As String)
        '<div id="Box1" style="z-index:5;top:24px;left:8px;width:109px;height:8px;border-color:#000000;border-style:solid;border-width:1px;">
        '    <table width="101px" height="1px"><tr><td>
        '    </td></tr></table>
        '</div>

        sbContent.Append(indent & "<DIV class=""i" & LineIndex(line) & """ style=""LEFT: " & line.Location.X & "px; WIDTH: " & line.Size.Width & "px; TOP: " & line.Location.Y & "px; HEIGHT: " & line.Size.Height & "px;"">" & ControlChars.NewLine)
        sbContent.Append(indent & "</DIV>" & ControlChars.NewLine)
    End Sub
    Private Sub HtmlFrame(ByVal frame As Model10.Frame, ByVal offsetY As Integer, ByVal indent As String)
        '<div id="Box1" style="z-index:5;top:24px;left:8px;width:109px;height:8px;border-color:#000000;border-style:solid;border-width:1px;">
        '    <table width="101px" height="1px"><tr><td>
        '    </td></tr></table>
        '</div>

        sbContent.Append(indent & "<DIV class=""f" & FrameIndex(frame) & """ style=""LEFT: " & frame.Location.X & "px; WIDTH: " & frame.Size.Width & "px; TOP: " & frame.Location.Y + offsetY & "px; HEIGHT: " & frame.Size.Height & "px;"">" & ControlChars.NewLine)
        sbContent.Append(indent & "</DIV>" & ControlChars.NewLine)
    End Sub
    Private Sub HtmlLabel(ByVal label As Model10.Label, ByVal offsetY As Integer, ByVal indent As String)
        '<div id="Field1" title="Employees.FirstName (String)" class="ad632283280149687500-0" style="top:668px;left:3px;width:189px;height:15px;">
        '    <table width="184px" border="0" cellpadding="0" cellspacing="0px"><tr><td>
        '        <table border="0" cellpadding="0" cellspacing="0"><tr><td class="fc632283280149687500-0">
        '            <a href="Margaret" class="fc632283280149687500-0" target="_self">
        '                Margaret
        '            </a>
        '        </td></tr></table>
        '    </td></tr></table>
        '</div>

        Dim k As Integer
        k = CInt(2 * label.BorderWidth)
        Dim noWrap As String
        If label.NoWrap Then noWrap = " noWrap"
        Dim title As String
        If label.ToolTip <> "" Then title = " title=""" & label.ToolTip & """"
        Dim direction As String
        If label.RightToLeft = Windows.Forms.RightToLeft.Yes Then direction = " dir=""rtl"""

        sbContent.Append(indent & "<DIV class=""f" & FrameIndex(label) & """ style=""LEFT: " & label.Location.X & "px; WIDTH: " & label.Size.Width & "px; TOP: " & label.Location.Y + offsetY & "px; HEIGHT: " & label.Size.Height & "px;""" & noWrap & title & ">" & ControlChars.NewLine)
        If label.NavigateUrl = "" Then
            sbContent.Append(indent & vbTab & "<SPAN class=""l" & LabelIndex(label) & """ style=""WIDTH: " & label.Size.Width - k & "px; HEIGHT: " & label.Size.Height - k & "px;""" & direction & ">" & ControlChars.NewLine)
            sbContent.Append(indent & vbTab & vbTab & label.Text & ControlChars.NewLine)
            sbContent.Append(indent & vbTab & "</SPAN>" & ControlChars.NewLine)
        Else
            Dim target As String
            If label.Target <> "" Then target = " target=""" & label.Target & """"

            sbContent.Append(indent & vbTab & "<A class=""l" & LabelIndex(label) & """ style=""WIDTH: " & label.Size.Width - k & "px; HEIGHT: " & label.Size.Height - k & "px;"" href=""" & label.NavigateUrl & """" & target & direction & " tabIndex=""" & label.TabIndex & """>" & ControlChars.NewLine)
            sbContent.Append(indent & vbTab & vbTab & label.Text & ControlChars.NewLine)
            sbContent.Append(indent & vbTab & "</A>" & ControlChars.NewLine)
        End If
        sbContent.Append(indent & "</DIV>" & ControlChars.NewLine)
    End Sub
    Private Sub HtmlPictureBox(ByVal pictureBox As Model10.PictureBox, ByVal offsetY As Integer, ByVal indent As String)
        '<div id="Field3" title="Blob Field" class="ad632283280149687500-1" style="z-index:15;top:665px;left:200px;width:192px;height:222px;">
        '    <a href="http://www.radplatform.com" target="_self">
        '        <img src="/crystalreportwebformviewer2/crystalimagehandler.aspx?dynamicimage=7b606959-390a-4864-9b74-80f5dc526be2.jpg" border="0" width="192px" height="222px" />
        '    </a>
        '</div>

        Dim title As String
        If pictureBox.ToolTip <> "" Then title = " title=""" & pictureBox.ToolTip & """"
        If pictureBox.Image Is Nothing Then
            Dim mainRect As New Drawing.Rectangle(pictureBox.Location.X, pictureBox.Location.Y, pictureBox.Size.Width, pictureBox.Size.Height)

            sbContent.Append(indent & "<DIV ms_positioning=""GridLayout"" class=""f" & FrameIndex(pictureBox) & """ style=""LEFT: " & mainRect.X & "px; WIDTH: " & mainRect.Width & "px; TOP: " & mainRect.Y + offsetY & "px; HEIGHT: " & mainRect.Height & "px;""" & title & ">" & ControlChars.NewLine)
            sbContent.Append(indent & "</DIV>" & ControlChars.NewLine)
        Else
            Dim i As Integer = -1
            If Not localPictures Is Nothing Then
                i = localPictures.IndexOf(pictureBox)
                If i = -1 Then
                    localPictures.Add(pictureBox)
                    i = localPictures.Count - 1
                End If
            End If

            Dim k As Integer = CInt(pictureBox.BorderWidth)
            Dim clipRect As Drawing.Rectangle = pictureBox.ClipRectangleF
            Dim mainRect As Drawing.Rectangle = clipRect

            clipRect.X = pictureBox.LeftMargin : clipRect.Y = pictureBox.TopMargin
            mainRect.Offset(pictureBox.Location.X - pictureBox.LeftMargin - k, pictureBox.Location.Y - pictureBox.TopMargin - k)
            mainRect.Width += pictureBox.LeftMargin + pictureBox.RightMargin + 2 * k
            mainRect.Height += pictureBox.TopMargin + pictureBox.BottomMargin + 2 * k

            Dim src As String
            If path2 = "" Then
                src = " src=""" & path1 & pictureBox.Key & """"
            Else
                src = " src=""" & path1 & "\img" & i + 1 & path2 & """"
            End If

            sbContent.Append(indent & "<DIV ms_positioning=""GridLayout"" class=""f" & FrameIndex(pictureBox) & """ style=""LEFT: " & mainRect.X & "px; WIDTH: " & mainRect.Width & "px; TOP: " & mainRect.Y + offsetY & "px; HEIGHT: " & mainRect.Height & "px;""" & title & ">" & ControlChars.NewLine)
            If pictureBox.NavigateUrl = "" Then
                sbContent.Append(indent & vbTab & "<IMG" & src & " style=""LEFT: " & clipRect.X & "px; WIDTH: " & clipRect.Width & "px; TOP: " & clipRect.Y & "px; HEIGHT: " & clipRect.Height & "px;"" width=""" & clipRect.Width & """ height=""" & clipRect.Height & """>" & ControlChars.NewLine)
            Else
                Dim target As String
                If pictureBox.Target <> "" Then target = " target=""" & pictureBox.Target & """"

                sbContent.Append(indent & vbTab & "<A href=""" & pictureBox.NavigateUrl & """" & target & " tabIndex=""" & pictureBox.TabIndex & """>" & ControlChars.NewLine)
                sbContent.Append(indent & vbTab & vbTab & "<IMG" & src & " style=""LEFT: " & clipRect.X & "px; WIDTH: " & clipRect.Width & "px; TOP: " & clipRect.Y & "px; HEIGHT: " & clipRect.Height & "px;"" width=""" & clipRect.Width & """ height=""" & clipRect.Height & """>" & ControlChars.NewLine)
                sbContent.Append(indent & vbTab & "</A>" & ControlChars.NewLine)
            End If
            sbContent.Append(indent & "</DIV>" & ControlChars.NewLine)
        End If
    End Sub
    Private Sub HtmlCheckBox(ByVal checkBox As Model10.CheckBox, ByVal offsetY As Integer, ByVal indent As String)
        Dim src As String
        If checkBox.Checked Then
            If path2 = "" Then
                src = " src=""../SystemImages/Checked.gif"""
            Else
                src = " src=""" & path1 & "\Checked" & path2 & """"
            End If
            checkedImage = True
        Else
            If path2 = "" Then
                src = " src=""../SystemImages/Unchecked.gif"""
            Else
                src = " src=""" & path1 & "\Unchecked" & path2 & """"
            End If
            uncheckedImage = True
        End If
        Dim title As String
        If checkBox.ToolTip <> "" Then title = " title=""" & checkBox.ToolTip & """"

        Dim checkPoint As Drawing.Point = checkBox.CheckPointF
        checkPoint.Offset(0, 0)
        sbContent.Append(indent & "<IMG class=""check""" & src & " style=""LEFT: " & checkPoint.X & "px; WIDTH: 11px; TOP: " & checkPoint.Y + offsetY & "px; HEIGHT: 11px;"" width=""11"" height=""11""" & title & ">" & ControlChars.NewLine)
    End Sub
    Private Sub HtmlMembers(ByVal members As Model10.MemberCollection, ByVal offsetY As Integer, ByVal pageNumber As Integer, ByVal indent As String)
        Dim mem As Model10.Member
        For Each mem In members
            Select Case mem.GetType.ToString
                Case "Model10.Frame" : HtmlFrame(CType(mem, Model10.Frame), offsetY, indent)
                Case "Model10.Line" : HtmlLine(CType(mem, Model10.Line), indent)
                Case "Model10.Label"
                    Dim lbl As Model10.Label = CType(mem, Model10.Label)
                    Select Case lbl.Value
                        Case ValueType.PageNumber
                            lbl.Text = (pageNumber).ToString
                        Case ValueType.PageCount
                            lbl.Text = mPages.Count.ToString
                    End Select
                    HtmlLabel(lbl, offsetY, indent)
                Case "Model10.PageNumber"
                    Dim lbl As Model10.Label = CType(mem, Model10.Label)
                    lbl.Text = (pageNumber).ToString
                    HtmlLabel(lbl, offsetY, indent)
                    lbl = Nothing
                Case "Model10.PageCount"
                    Dim lbl As Model10.Label = CType(mem, Model10.Label)
                    lbl.Text = mPages.Count.ToString
                    HtmlLabel(lbl, offsetY, indent)
                    lbl = Nothing
                Case "Model10.PictureBox" : HtmlPictureBox(CType(mem, Model10.PictureBox), offsetY, indent)
                Case "Model10.CheckBox" : HtmlCheckBox(CType(mem, Model10.CheckBox), offsetY, indent)
                Case "Model10.Button"
                Case "Model10.Chart" '...
                Case Else
                    Stop
            End Select
        Next : mem = Nothing
    End Sub

    Public Function GetHtml(ByVal pageNumber As Integer) As String
        '<style>
        '    div {position:absolute; z-index:25}
        '    a {text-decoration:none}
        '    a img {border-style:none; border-width:0}
        '	.fc632283280149687500-0 {font-size:9pt;color:#000000;font-family:Times New Roman;font-weight:bold;}
        '	.ad632283280149687500-0 {border-color:#000000;border-style:solid;border-width:0px;border-left-style:solid;border-left-width:1;border-right-style:solid;border-right-width:1;border-top-style:solid;border-top-width:1;border-bottom-style:solid;border-bottom-width:1;}
        '</style>

        sbStyle = New Text.StringBuilder
        sbContent = New Text.StringBuilder
        lines = New ArrayList
        frames = New ArrayList
        labels = New ArrayList
        'localPictures = New ArrayList
        checkedImage = False : uncheckedImage = False
        path1 = "GetReportImage.aspx?Level=" & level & "&Index=" & index & "&Key="
        path2 = ""

        sbStyle.Append(vbTab & vbTab & vbTab & "A {TEXT-DECORATION: none}" & ControlChars.NewLine)
        sbStyle.Append(vbTab & vbTab & vbTab & ".check {DISPLAY: inline; POSITION: absolute}" & ControlChars.NewLine)
        sbStyle.Append(vbTab & vbTab & vbTab & ".section {DISPLAY: inline; POSITION: absolute}" & ControlChars.NewLine)

        Dim ind As String = vbTab & vbTab & vbTab & vbTab
        Dim offsetY As Integer = 0
        webColConverter = New System.Web.UI.WebControls.WebColorConverter

        If Not mPageHeader Is Nothing Then
            HtmlMembers(mPageHeader.Members, offsetY, pageNumber, ind)
            offsetY += mPageHeader.Height
        End If
        '---------------------------------------
        Dim page As Model10.Page = mPages(pageNumber - 1)

        Dim sec As Model10.Section
        For Each sec In page.Sections
            Dim bkColor As String = webColConverter.ConvertToString(sec.BackColor)
            sbContent.Append(ind & "<DIV ms_positioning=""GridLayout"" class=""section"" style=""BACKGROUND-COLOR: " & bkColor & "; LEFT: " & sec.Location.X & "px; TOP: " & sec.Location.Y + offsetY & "px; WIDTH: " & sec.Table.Width & "px; HEIGHT: " & sec.Height & "px;"">" & ControlChars.NewLine)
            HtmlMembers(sec.Members, 0, pageNumber, ind & vbTab)
            sbContent.Append(ind & "</DIV>" & ControlChars.NewLine)
        Next : sec = Nothing

        page = Nothing
        '---------------------------------------
        offsetY += contentSize.Height
        If Not mPageFooter Is Nothing Then
            HtmlMembers(mPageFooter.Members, offsetY, pageNumber, ind)
            offsetY += mPageFooter.Height
        End If

        webColConverter = Nothing

        Dim rtl As String
        Select Case mRightToLeft
            Case Windows.Forms.RightToLeft.No : rtl = "ltr"
            Case Windows.Forms.RightToLeft.Yes : rtl = "rtl"
        End Select
        If rtl <> "" Then rtl = " dir=""" & rtl & """"

        GetHtml &= vbTab & vbTab & "<style media=""print"">.sterio {OVERFLOW: visible}" & ControlChars.NewLine
        GetHtml &= vbTab & vbTab & "</style>" & ControlChars.NewLine
        GetHtml &= vbTab & vbTab & "<style media=""screen"">.sterio {OVERFLOW: auto}" & ControlChars.NewLine
        GetHtml &= vbTab & vbTab & "</style>" & ControlChars.NewLine
        'GetHtml &= vbTab & vbTab & "<style media=""print"">.dual {OVERFLOW: visible}" & ControlChars.NewLine
        'GetHtml &= vbTab & vbTab & "</style>" & ControlChars.NewLine
        'GetHtml &= vbTab & vbTab & "<style media=""screen"">.dual {OVERFLOW: visible}" & ControlChars.NewLine
        'GetHtml &= vbTab & vbTab & "</style>" & ControlChars.NewLine
        GetHtml &= vbTab & vbTab & "<style>" & ControlChars.NewLine
        GetHtml &= sbStyle.ToString
        GetHtml &= vbTab & vbTab & "</style>" & ControlChars.NewLine
        GetHtml &= vbTab & vbTab & "<DIV class=""sterio"" style=""DISPLAY: inline; WIDTH: 100%; HEIGHT: 100%;""" & rtl & ">" & ControlChars.NewLine
        GetHtml &= vbTab & vbTab & vbTab & "<DIV ms_positioning=""GridLayout"" style=""DISPLAY: inline; OVERFLOW: hidden; POSITION: absolute; WIDTH:" & contentSize.Width & "px; HEIGHT:" & offsetY & "px;"">" & ControlChars.NewLine
        GetHtml &= sbContent.ToString
        GetHtml &= vbTab & vbTab & vbTab & "</DIV>" & ControlChars.NewLine
        GetHtml &= vbTab & vbTab & "</DIV>" & ControlChars.NewLine

        'localPictures.Clear() : localPictures = Nothing
        lines.Clear() : lines = Nothing
        frames.Clear() : frames = Nothing
        labels.Clear() : labels = Nothing
        sbStyle = Nothing
        sbContent = Nothing
    End Function
    Public Sub SaveHtml(ByVal fromPageNumber As Integer, ByVal toPageNumber As Integer, ByVal include As Boolean, ByVal open As Boolean, ByVal file As String)
        Dim d As String = IO.Path.GetDirectoryName(file)
        Dim x As String = IO.Path.GetExtension(file)
        Dim n As String = IO.Path.GetFileNameWithoutExtension(file)

        If x = ".htm" Or x = ".html" Then
            sbStyle = New Text.StringBuilder
            sbContent = New Text.StringBuilder
            lines = New ArrayList
            frames = New ArrayList
            labels = New ArrayList
            localPictures = New ArrayList
            checkedImage = False : uncheckedImage = False
            path1 = n & "_files"
            path2 = ".bmp"

            sbStyle.Append(vbTab & vbTab & vbTab & "A {TEXT-DECORATION: none}" & ControlChars.NewLine)
            sbStyle.Append(vbTab & vbTab & vbTab & ".check {DISPLAY: inline; POSITION: absolute}" & ControlChars.NewLine)
            sbStyle.Append(vbTab & vbTab & vbTab & ".section {DISPLAY: inline; POSITION: absolute}" & ControlChars.NewLine)

            Dim ind As String = vbTab & vbTab & vbTab & vbTab
            Dim offsetY As Integer
            webColConverter = New System.Web.UI.WebControls.WebColorConverter

            Dim i As Integer
            For i = fromPageNumber To toPageNumber
                If include Then
                    offsetY += 0
                    If Not mPageHeader Is Nothing Then
                        HtmlMembers(mPageHeader.Members, offsetY, i, ind)
                        offsetY += mPageHeader.Height
                    End If
                    '---------------------------------------
                    Dim page As Model10.Page = mPages(i - 1)

                    Dim sec As Model10.Section
                    For Each sec In page.Sections
                        Dim bkColor As String = webColConverter.ConvertToString(sec.BackColor)
                        sbContent.Append(ind & "<DIV ms_positioning=""GridLayout"" class=""section"" style=""BACKGROUND-COLOR: " & bkColor & "; LEFT: " & sec.Location.X & "px; TOP: " & sec.Location.Y + offsetY & "px; WIDTH: " & sec.Table.Width & "px; HEIGHT: " & sec.Height & "px;"">" & ControlChars.NewLine)
                        HtmlMembers(sec.Members, 0, i, ind & vbTab)
                        sbContent.Append(ind & "</DIV>" & ControlChars.NewLine)
                    Next : sec = Nothing

                    page = Nothing
                    '---------------------------------------
                    offsetY += contentSize.Height
                    If Not mPageFooter Is Nothing Then
                        HtmlMembers(mPageFooter.Members, offsetY, i, ind)
                        offsetY += mPageFooter.Height
                    End If
                Else
                    '---------------------------------------
                    Dim page As Model10.Page = mPages(i - 1)

                    Dim sec As Model10.Section
                    For Each sec In page.Sections
                        HtmlMembers(sec.Members, offsetY, i, ind)
                    Next : sec = Nothing

                    page = Nothing
                    '---------------------------------------
                    offsetY += mPages(i - 1).Height
                End If
            Next

            webColConverter = Nothing

            Dim rtl As String
            Select Case mRightToLeft
                Case Windows.Forms.RightToLeft.No : rtl = "ltr"
                Case Windows.Forms.RightToLeft.Yes : rtl = "rtl"
            End Select
            If rtl <> "" Then rtl = " dir=""" & rtl & """"

            Dim c As String
            c &= "<!DOCTYPE HTML PUBLIC ""-//W3C//DTD HTML 4.0 Transitional//EN"">" & ControlChars.NewLine
            c &= "<html>" & ControlChars.NewLine
            c &= vbTab & "<head>" & ControlChars.NewLine
            c &= vbTab & vbTab & "<title>" & name & " Preview" & "</title>" & ControlChars.NewLine
            c &= vbTab & vbTab & "<meta name=""GENERATOR"" content=""Microsoft Visual Studio .NET 7.1"">" & ControlChars.NewLine
            c &= vbTab & vbTab & "<meta name=""vs_targetSchema"" content=""http://schemas.microsoft.com/intellisense/ie5"">" & ControlChars.NewLine
            c &= vbTab & vbTab & "<style media=""print"">.sterio {OVERFLOW: visible}" & ControlChars.NewLine
            c &= vbTab & vbTab & "</style>" & ControlChars.NewLine
            c &= vbTab & vbTab & "<style media=""screen"">.sterio {OVERFLOW: auto}" & ControlChars.NewLine
            c &= vbTab & vbTab & "</style>" & ControlChars.NewLine
            'c &= vbTab & vbTab & "<style media=""print"">.dual {OVERFLOW: visible}" & ControlChars.NewLine
            'c &= vbTab & vbTab & "</style>" & ControlChars.NewLine
            'c &= vbTab & vbTab & "<style media=""screen"">.dual {OVERFLOW: visible}" & ControlChars.NewLine
            'c &= vbTab & vbTab & "</style>" & ControlChars.NewLine
            c &= vbTab & vbTab & "<style>" & ControlChars.NewLine
            c &= sbStyle.ToString
            c &= vbTab & vbTab & "</style>" & ControlChars.NewLine
            c &= vbTab & "</head>" & ControlChars.NewLine
            c &= vbTab & "<body language=""javascript"" scroll=""no"" bottomMargin=""0"" leftMargin=""0"" topMargin=""0"" rightMargin=""0"">" & ControlChars.NewLine
            c &= vbTab & vbTab & "<DIV class=""sterio"" style=""DISPLAY: inline; WIDTH: 100%; HEIGHT: 100%;""" & rtl & ">" & ControlChars.NewLine
            c &= vbTab & vbTab & vbTab & "<DIV ms_positioning=""GridLayout"" style=""DISPLAY: inline; OVERFLOW: hidden; POSITION: absolute; WIDTH:" & contentSize.Width & "px; HEIGHT:" & offsetY & "px;"">" & ControlChars.NewLine
            c &= sbContent.ToString
            c &= vbTab & vbTab & vbTab & "</DIV>" & ControlChars.NewLine
            c &= vbTab & vbTab & "</DIV>" & ControlChars.NewLine
            c &= vbTab & "</body>" & ControlChars.NewLine
            c &= "</html>" & ControlChars.NewLine
            Dim sw As IO.StreamWriter = New IO.StreamWriter(file)
            sw.Write(c)
            sw.Close() : sw = Nothing

            If IO.Directory.Exists(d & "\" & path1) Then
                Dim dirs() As String = IO.Directory.GetFiles(d & "\" & path1)
                Dim dir As String
                For Each dir In dirs
                    IO.File.Delete(dir)
                Next
            Else
                IO.Directory.CreateDirectory(d & "\" & path1)
            End If

            Dim pic As Model10.PictureBox
            For Each pic In localPictures
                pic.GetImageF(Drawing.Color.White).Save(d & "\" & path1 & "\img" & localPictures.IndexOf(pic) + 1 & path2, Drawing.Imaging.ImageFormat.Bmp)
            Next : pic = Nothing

            If checkedImage Then
                Model10.CheckBox.GetImageF(True).Save(d & "\" & path1 & "\Checked" & path2, Drawing.Imaging.ImageFormat.Bmp)
            End If
            If uncheckedImage Then
                Model10.CheckBox.GetImageF(False).Save(d & "\" & path1 & "\Unchecked" & path2, Drawing.Imaging.ImageFormat.Bmp)
            End If

            localPictures.Clear() : localPictures = Nothing
            lines.Clear() : lines = Nothing
            frames.Clear() : frames = Nothing
            labels.Clear() : labels = Nothing
            sbStyle = Nothing
            sbContent = Nothing
        ElseIf x = ".pdf" Then
        ElseIf x = ".xml" Then
        End If
        If open Then Process.Start(file)
    End Sub
End Class

Public Class Row
    Private ReadOnly mBodies As Model10.ContentCollection
    Private mCurrent As Model10.Current
    Private mDetail As Model10.Detail
    Private mIndex As Integer

    Public Sub New()
        MyBase.New()

        mBodies = New Model10.ContentCollection
        mCurrent = Nothing
        mDetail = Nothing
        mIndex = 0
    End Sub

    Public ReadOnly Property Bodies() As Model10.ContentCollection
        Get
            Return mBodies
        End Get
    End Property
    Public Property Current() As Model10.Current
        Get
            Return mCurrent
        End Get
        Set(ByVal Value As Model10.Current)
            mCurrent = Value
        End Set
    End Property
    Public Property Detail() As Model10.Detail
        Get
            Return mDetail
        End Get
        Set(ByVal Value As Model10.Detail)
            mDetail = Value
        End Set
    End Property
    Public Property Index() As Integer
        Get
            Return mIndex
        End Get
        Set(ByVal Value As Integer)
            mIndex = Value
        End Set
    End Property
End Class
Public Class Content
    Private mGroupFooter As Model10.Grouper
    Private mGroupHeader As Model10.Grouper
    Private mHeight As Integer
    Private mKeepTogether As Model10.KeepMode
    Private mRows As Model10.RowCollection
    Private mSideMargin As Integer
    Private mWidth As Integer

    Public Sub Clear()
        mGroupFooter = Nothing
        mGroupHeader = Nothing
        mRows.Clear()
    End Sub
    Public Sub New()
        MyBase.New()

        mGroupFooter = Nothing
        mGroupHeader = Nothing
        mHeight = 0
        mKeepTogether = KeepMode.No
        mRows = New Model10.RowCollection
        mSideMargin = 0
        mWidth = 0
    End Sub
    Public Sub New(ByVal table As Model10.Table)
        MyBase.New()

        mGroupFooter = Nothing
        mGroupHeader = Nothing
        mHeight = 0
        mKeepTogether = table.KeepTogether
        mRows = New Model10.RowCollection
        mSideMargin = 0
        mWidth = table.Width
    End Sub

    Public Property GroupFooter() As Model10.Grouper
        Get
            Return mGroupFooter
        End Get
        Set(ByVal Value As Model10.Grouper)
            mGroupFooter = Value
        End Set
    End Property
    Public Property GroupHeader() As Model10.Grouper
        Get
            Return mGroupHeader
        End Get
        Set(ByVal Value As Model10.Grouper)
            mGroupHeader = Value
        End Set
    End Property
    Public Property Height() As Integer
        Get
            Return mHeight
        End Get
        Set(ByVal Value As Integer)
            mHeight = Value
        End Set
    End Property
    Public Property KeepTogether() As Model10.KeepMode
        Get
            Return mKeepTogether
        End Get
        Set(ByVal Value As Model10.KeepMode)
            mKeepTogether = Value
        End Set
    End Property
    Public Property Rows() As Model10.RowCollection
        Get
            Return mRows
        End Get
        Set(ByVal Value As Model10.RowCollection)
            mRows = Value
        End Set
    End Property
    Public Property SideMargin() As Integer
        Get
            Return mSideMargin
        End Get
        Set(ByVal Value As Integer)
            mSideMargin = Value
        End Set
    End Property
    Public Property Width() As Integer
        Get
            Return mWidth
        End Get
        Set(ByVal Value As Integer)
            mWidth = Value
        End Set
    End Property
End Class
Public Class Page
    Private mHeight As Integer
    Private ReadOnly mSections As Model10.SectionCollection

    Public Sub New()
        MyBase.New()

        mHeight = 0
        mSections = New Model10.SectionCollection
    End Sub

    Public Property Height() As Integer
        Get
            Return mHeight
        End Get
        Set(ByVal Value As Integer)
            mHeight = Value
        End Set
    End Property
    Public ReadOnly Property Sections() As Model10.SectionCollection
        Get
            Return mSections
        End Get
    End Property
End Class

<Serializable()> Public Class SectionCollection
    Inherits CollectionBase

    Public Function Contains(ByVal value As Model10.Section) As Boolean
        Return MyBase.List.Contains(value)
    End Function
    Public Sub New()
        MyBase.New()
    End Sub

    Default Public ReadOnly Property Item(ByVal index As Integer) As Model10.Section
        Get
            Return CType(MyBase.List.Item(index), Model10.Section)
        End Get
    End Property
    Public Sub Add(ByVal value As Model10.Section)
        MyBase.List.Add(value)
    End Sub
    Public Sub Insert(ByVal index As Integer, ByVal value As Model10.Section)
        MyBase.List.Insert(index, value)
    End Sub
    Public Sub Remove(ByVal value As Model10.Section)
        MyBase.List.Remove(value)
    End Sub
End Class

Public Class RowCollection
    Inherits CollectionBase

    Default Public ReadOnly Property Item(ByVal Index As Integer) As Model10.Row
        Get
            Return CType(MyBase.List.Item(Index), Model10.Row)
        End Get
    End Property
    Public Sub Add(ByVal Value As Model10.Row)
        MyBase.List.Add(Value)
    End Sub
    Public Sub Insert(ByVal Index As Integer, ByVal Value As Model10.Row)
        MyBase.List.Insert(Index, Value)
    End Sub
    Public Sub Remove(ByVal Value As Model10.Row)
        MyBase.List.Remove(Value)
    End Sub
End Class
Public Class ContentCollection
    Inherits CollectionBase

    Default Public ReadOnly Property Item(ByVal Index As Integer) As Model10.Content
        Get
            Return CType(MyBase.List.Item(Index), Model10.Content)
        End Get
    End Property
    Public Sub Add(ByVal Value As Model10.Content)
        MyBase.List.Add(Value)
    End Sub
    Public Sub Insert(ByVal Index As Integer, ByVal Value As Model10.Content)
        MyBase.List.Insert(Index, Value)
    End Sub
    Public Sub Remove(ByVal Value As Model10.Content)
        MyBase.List.Remove(Value)
    End Sub
End Class
Public Class PageCollection
    Inherits CollectionBase

    Default Public ReadOnly Property Item(ByVal Index As Integer) As Model10.Page
        Get
            Return CType(MyBase.List.Item(Index), Model10.Page)
        End Get
    End Property
    Public Sub Add(ByVal Value As Model10.Page)
        MyBase.List.Add(Value)
    End Sub
    Public Sub Insert(ByVal Index As Integer, ByVal Value As Model10.Page)
        MyBase.List.Insert(Index, Value)
    End Sub
    Public Sub Remove(ByVal Value As Model10.Page)
        MyBase.List.Remove(Value)
    End Sub
End Class

Public Class RowEventArgs
    Inherits EventArgs

    Private ReadOnly mDataRow As DataRowView
    Private ReadOnly mRowIndex As Integer

    Public Sub New(ByVal dataRow As DataRowView, ByVal rowIndex As Integer)
        MyBase.New()

        mDataRow = dataRow
        mRowIndex = rowIndex
    End Sub

    Public ReadOnly Property DataRow() As DataRowView
        Get
            Return mDataRow
        End Get
    End Property
    Public ReadOnly Property RowIndex() As Integer
        Get
            Return mRowIndex
        End Get
    End Property
End Class
Public Class LookupEventArgs
    Inherits EventArgs

    Private ReadOnly mDataRowIndex As Integer
    Private ReadOnly mDataView As DataView
    Private ReadOnly mRelation As Model10.Relation
    Private ReadOnly mTable As Model10.Table

    Public Sub New(ByVal dataRowIndex As Integer, ByVal dataView As DataView, ByVal relation As Model10.Relation, ByVal table As Model10.Table)
        MyBase.New()

        mDataRowIndex = dataRowIndex
        mDataView = dataView
        mRelation = relation
        mTable = table
    End Sub

    Public ReadOnly Property DataRowIndex() As Integer
        Get
            Return mDataRowIndex
        End Get
    End Property
    Public ReadOnly Property DataView() As DataView
        Get
            Return mDataView
        End Get
    End Property
    Public ReadOnly Property Relation() As Model10.Relation
        Get
            Return mRelation
        End Get
    End Property
    Public ReadOnly Property Table() As Model10.Table
        Get
            Return mTable
        End Get
    End Property
End Class
Public Class DrilldownEventArgs
    Inherits EventArgs

    Private ReadOnly mCurrent As Model10.Current

    Public Sub New(ByVal current As Model10.Current)
        MyBase.New()

        mCurrent = current
    End Sub

    Public ReadOnly Property Current() As Model10.Current
        Get
            Return mCurrent
        End Get
    End Property
End Class
